<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>




  
  
  
  
  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">




  
  
  
  
  <title>Generating communication layer</title>
</head>


<body>




<div style="text-align: center;"><big><big><big><span style="font-weight: bold;">Generating communication layer</span></big></big></big><br>




</div>




<br>




<br>




<br>




<br>




<big style="font-weight: bold;"><big><a name="Contents"></a>Contents<br>




</big></big>
<ul>




  <li><a href="#Introduction">Introduction</a></li>




  <li><a href="#Limitations">Limitations</a></li>




  <li><a href="#Step_by_step">Step by step</a><br>




  </li>




  <li><a href="#Keywords">Keywords</a></li>




  <li><a href="#Command_line_arguments">Command line arguments</a><br>




  </li>




  <li><a href="#See_also">See also</a><br>




  </li>




</ul>




<br>




<br>




<br>




<br>




<br>




<big style="font-weight: bold;"><big><a name="Introduction"></a>Introduction</big></big><br>




<p>&nbsp;&nbsp;&nbsp; This manual deals with coidgen - the tool that's
responsible for generating client- and server-side communication code
over
network. We wanted it to meet the following requirements:</p>




<ul>




  <li>
    
    
    
    
    <p> It should be possible to generate network communication layer
for any class solely from its declaration, given that programmer
decorates the declaration with some control tokens. These tokens will
be either empty defines or comments with special formatting, that is
they are not going to affect the original source in any way. The
generator should be able to parse any C++
header and process the input it recognizes, while ignoring everything
else. It by itself does not touch the header file in any way.<br>




    </p>




  </li>




  <li>
    
    
    
    
    <p>The generator basically builds the communtication layer for
class methods that are preceded by <span style="font-family: monospace; font-weight: bold;">net_fnc</span>
token in the
declaration. Only these methods are exported, i.e. the generator
outputs communication code to carry out the calls to these methods
remotely.</p>




  </li>




  <li>
    
    
    
    
    <p>To generate the code that encodes and decodes arbitrary method
arguments and transfers them to and from the server, the generator
needs additional information about the arguments, namely if they
transfer parameters into the method (in, data transfered from client to
server only), or they transfer results from the method call (out, data
transfered from server back to client), or if they are bidirectional
(inout, data transfered to server and back).<br>




The control tokens used are <span style="font-family: monospace; font-weight: bold;">net_in</span> for
input arguments,<span style="font-family: monospace;"> <span style="font-weight: bold;">net_out</span> </span>and<span style="font-family: monospace;"> <span style="font-weight: bold;">net_fetch</span>
    </span>for output arguments and<span style="font-family: monospace;">
    <span style="font-weight: bold;">net_inout</span> </span>for
bidirectional ones.<br>




    </p>




  </li>




  <li>
    
    
    
    
    <p>The generator is designed to run as a pre-build step for a
compiler - it takes the header file name as argument and updates the
network code if necessary.</p>




  </li>




  <li>
    
    
    
    
    <p>Version management - COID server has ability to run multiple
versions of services with the same name. It recognizes major and minor
version number of any service and hands to a remote client a connection
to the one that best fits the version for what the client was compiled.
This allows for serving clients that are older or newer than the
service running under the COID server, provided the versions do not
differ too much. You need
a client with the major version number equal to the major version
number of the running service, but minor
versions can be different. So it's important to know
when major and/or minor version numbers have to be changed. For now,
minor version number changes only if a method is added / deleted,
major version number if a difference in a method is detected (coidgen
compares
source service header and a "reference" binary (.dev) or old
dispatch.cpp).</p>




  </li>




  <li>
    
    
    
    
    <p>Communication layer consists of 3 files: client.cpp, client.h
and
dispatch.cpp, each prefixed with the
class name and underscore. The client application should include
client.h and link with client.cpp, and the service (on the server side)
should link with
dispatch.cpp</p>




  </li>




  <li>Code for both client side and service side are generated. The
client side contains declaration of client class <span style="font-family: monospace;">(</span><span style="font-style: italic;">class</span><span style="font-family: monospace;">_client) </span>with
the exported methods, that can be instantiated and dealt with as with
ordinary C++ class, without basically knowing that the call is carried
out remotely. The client.cpp contains method call encoding and decoding
code.<br>




Server side generated code contains dispatcher that decodes client and
framework calls and links them with implementation.<br>




  </li>




  <li>
    
    
    
    
    <p>Client's code at connect time checks whether client resides in
the same process as server, and if so it sets up a function pointer
table to call server (service) directly (probably next coid version
will be able to detect if these two processes are on the same machine,
and then use interprocess communication mechanisms to speed up function
calls between processes).</p>




  </li>




  <li>Client's class should be thread-safe.<br>




  </li>




</ul>




<br>




<br>




<br>




<big style="font-weight: bold;"><big><a name="Limitations"></a>Limitations<br>




</big></big>&nbsp;&nbsp;&nbsp; <span style="font-style: italic;">Common
limitations</span>:<br>




<ul>




  <li>
    
    
    
    
    <p>you cannot directly transfer pointers. Typically server and
client run in
different processes, so it wouldn't make sense to do so. So coidgen
assumes you transfer single object or an array of objects pointed to by
the pointers. Nonetheless, transfering pointer value (address) in
certain situations proves useful, <a href="function_argument_format.html">this document</a> describes
what can
and what cannot be declared as a function argument.</p>




  </li>




  <li>
    
    
    
    
    <p>parameters for constructor are ignored. Use <span style="font-family: monospace;">accept_connect() </span>or<span style="font-family: monospace;"> </span><span style="font-family: monospace;"><span style="font-family: monospace;">accept_connect_shared()</span></span>
as
your initialization routines, they accept any number of arguments.
Another way of initialization of you object is to use <span style="font-family: monospace;">accept_startup_params()</span> routine.<span style="font-family: monospace;"><br>




    </span></p>




  </li>




  <li>
    
    
    
    
    <p><span style="text-decoration: underline; color: rgb(51, 51, 255);">binstream</span>
operators for special types. Because we are transfering
data through the network pipe and we don't have any idea what we're
transfering, you are responsible for writing operators <span style="font-family: monospace;">&lt;&lt;</span> and <span style="font-family: monospace;">&gt;&gt;</span> that stream
your custom objects. Basic types have the stream operators written
already. If you use only non-pointer
members, it's easy, just implement them as raw reads and writes of binstream (if they have a
trivial copy constructor) or use sequence of operators on all members.
But if your object
contains pointers, you must use more sophisticated methods to be able
to restore them
on the opposite side of the network.</p>




  </li>




  <li>
    
    
    
    
    <p>clients are thread-safe except the <span style="font-family: monospace; font-weight: bold;"><a href="opcd_type.html">opcd</a>
_coid_err_code</span>
member in COID_CLIENT base class (see coidclient.h). It's recommended
that you use <a href="opcd_type.html"><span style="font-family: monospace; font-weight: bold;">opcd</span></a>
for return types of your methods, because then the server knows how
to return errors that occur outside the methods, such as communication
errors, deletion of objects and other. If the return
value is not <span style="font-family: monospace;">opcd</span>,
framework errors are stored in <span style="font-family: monospace;">_coid_err_code</span>
member of the client class after a method is called. If client is used
by a single thread, error can be accessed normally through <span style="font-family: monospace;">get_last_error()</span> method, but
simultaneous calls from multiple
threads may result in incorrect values.</p>




  </li>




</ul>




&nbsp;&nbsp;&nbsp; <span style="font-style: italic;">Syntax limitations</span>:<br>




<ul>




  <li>every method argument must have a name (otherwise we would have
to
parse all
headers in every path to distinguish between #defines or typedefs and
argument names)</li>




  <li>only one exported class (class containing marked methods for
which the network communication should be generated) per header is
supported (yet).<br>




  </li>




</ul>




<br>




<br>




<br>




<br>




<big><big><span style="font-weight: bold;"><a name="Step_by_step"></a>Step
by step<br>




</span></big></big><span style="font-weight: bold;"><br>




</span>&nbsp;&nbsp;&nbsp; First, let's say we already have a class
without
networking support and we want to add it there:<br>




file clc.h:<br>




<div style="margin-left: 40px; font-family: monospace;">const char *
global_err_strings[] = {<br>




&nbsp;&nbsp;&nbsp; "Ok", "Error"<br>




};<br>




...<br>




</div>




<div style="margin-left: 40px;"><span style="font-family: monospace;">class
Calculator</span><br style="font-family: monospace;">




<span style="font-family: monospace;">{</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; int
_last_error;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ...</span><br style="font-family: monospace;">




<span style="font-family: monospace;">public:</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; Calculator() :
_last_error(0) {}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; double
evaluate( const char * what ) {return 0.0;}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; const char *
get_error() { return
global_err_strings[_last_error]; }</span><br style="font-family: monospace;">




<span style="font-family: monospace;">};</span><br>




</div>




<br>




To make it available over network, we have to do these 5 (6) steps:<br>




<ol>




  <li>add line #include "coid/coidsvc/coidsvc.h" into the header</li>




  <li>make class contain at least one 'net_fnc' marked method (simply
add "net_fnc" in front of methods <span style="font-family: monospace;">evalute()</span>
and <span style="font-family: monospace;">get_error()</span>)</li>




  <li>decorate arguments with keywords (net_in /
net_out / ..., see <a href="#Keywords">keywords</a> below). Since
our argument 'what' is input, we don't have to write "net_in" there.<br>




  </li>




  <li>use coidgen tool and generate all the necessary files
(clc_client.h, clc_client.cpp and clc_dispatch.cpp)<br>




  </li>




  <li>compile clc_client.cpp and add it to our project (for client
side) and clc_dispatch.cpp for server side.<br>




  </li>




  <li>If you already use your class somewhere, change every occurence
of <span style="font-family: monospace;">Calculator</span> to <span style="font-family: monospace;">Calculator_client</span>
(class name in clc_client.h is <span style="font-family: monospace;">Calculator_client</span>).
Then, we also have to include our new
clc_client.h instead of clc.h and add <span style="font-family: monospace;">connect()</span> call after
Calculator_client constructor (see below).<br>




  </li>




</ol>




<br>




So the class will now look like this:<br>




file clc.h:<br>




<div style="margin-left: 40px;"><span style="font-family: monospace;">#include
"coid/coidsvc/coidsvc.h"</span><br style="font-family: monospace;">




<br style="font-family: monospace;">




<span style="font-family: monospace;">class Calculator</span><br style="font-family: monospace;">




<span style="font-family: monospace;">{</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; int
_last_error;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ...</span><br style="font-family: monospace;">




<span style="font-family: monospace;">public:</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; Calculator() :
_last_error(0) {}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; </span><span style="font-weight: bold; font-family: monospace;">net_fnc</span><span style="font-family: monospace;">
double evaluate( const char * what ) {return 0.0;}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; </span><span style="font-weight: bold; font-family: monospace;">net_fnc</span><span style="font-family: monospace;">
const char * get_error() { return global_err_strings[_last_error];
}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">};</span><br>




</div>




<br>




And client class in file clc_client.h:<br>




<div style="margin-left: 40px;"><span style="font-family: monospace;">...<br>




</span><span style="font-family: monospace;">class Calculator_client</span><br style="font-family: monospace;">




<span style="font-family: monospace;">{<br>




&nbsp;&nbsp;&nbsp; ...<br style="font-family: monospace;">




</span><span style="font-family: monospace;"></span><span style="font-family: monospace;">public:<br>




&nbsp;&nbsp;&nbsp; opcd connect(&nbsp; const char * coid_address=NULL,
uint coid_flags=ConnectFlags::xACCESS_MODE&nbsp; );<br>




&nbsp;&nbsp;&nbsp; opcd connect_within( comm_mutex_reg &amp;
coid_channel );<br>




&nbsp;&nbsp;&nbsp; opcd connect_shared( uint coid_obj_id,&nbsp; const
char * coid_address=NULL, uint
coid_flags=ConnectFlags::xACCESS_MODE&nbsp; );<br>




<br>




&nbsp;&nbsp;&nbsp; double evaluate( const char * what );<br>




&nbsp;&nbsp;&nbsp; const char * get_error();</span><span style="font-family: monospace;"><br>




};</span><br>




</div>




<br>




Because we didn't use <span style="font-family: monospace;">accept_connect()</span>
special method in clc.h,
<span style="font-family: monospace;">connect()</span> method on the
client side contains only two arguments. First one (<span style="font-family: monospace;">coid_address) </span>can be valid
string "server_address:port", empty string ("") which means that coid
name server will be asked for the address, or finally NULL (the same as
"localhost:55099"). The second argument (<span style="font-family: monospace;">coid_flags</span>) limits
connection type (direct, interprocess or remote). E.g. you may want to
connect to service only if it's in the same process as client. In this
case, use flag <span style="font-family: monospace;">ConnectFlags::fACCESS_MODE_DIRECT</span>.<br>




Note: <span style="font-family: monospace;">connect()</span> method <span style="font-weight: bold;">must</span> be called
before any of the others.<br>




<br>




&nbsp;&nbsp;&nbsp; Method <span style="font-family: monospace;"><span style="font-family: monospace;">Calculator_client::</span></span><span style="font-family: monospace;">get_error() </span>returns a
string. If you think about it, you could find out the way it travels to
client: it's inserted into a network packet on the server side, sent to
client, reassembled back to <span style="font-weight: bold;">dynamically</span>
allocated string there and returned from method call. No other handling
is done by coid framework. That means you are responsible for deleting
it when you no longer need it.<br>




And a simple example how to use client:<br>




<br>




<div style="margin-left: 40px; font-family: monospace;">#include
"clc_client.h"<br>




<br>




</div>




<div style="margin-left: 40px;"><span style="font-family: monospace;">bool
client_example() {</span><br style="font-family: monospace;">




<div style="margin-left: 40px; font-family: monospace;">Calculator_client
calc;<br>




opcd e = calc.connect( "server_addr:55099" );<br>




if( e ) return false;&nbsp; // connect failed, the
return value 'e' says more about the failure<br>




&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; &nbsp; // (always check this value, what
if the server is down ?)<br>




double result = calc.evaluate( "2+2" );<br>




if( calc.get_last_error() ) return false;&nbsp; // check for framework
error of "calc.evaluate()" method call<br>




...<br>




return true;<br>




</div>




<span style="font-family: monospace;">}</span><br>




</div>




<br>




This could be all, but if you want to use this client by two or more
threads (on client side), the "COID_CLIENT::_coid_err_code" variable
(returned by <span style="font-family: monospace;">get_last_error() </span>method)
is not
thread-safe, so you
may get improper errors (or non-error values instead of errors). That's
why we recommend you to change return types of all methods to <a style="font-weight: bold;" href="opcd_type.html">opcd</a>
type (in service header, that is clc.h) and transfer current return
values as
an output arguments:<br>




<br>




clc.h:<br>




<div style="margin-left: 40px; font-family: monospace;">class Calculator<br>




{<br>




&nbsp;&nbsp;&nbsp; int _last_error;<br>




&nbsp;&nbsp;&nbsp; ...<br>




public:<br>




&nbsp;&nbsp;&nbsp; Calculator() : _last_error(0) {}<br>




<br>




&nbsp;&nbsp;&nbsp; // Tip: you can add comment in front of every
method. It
will appear in clc_client.h<br>




&nbsp;&nbsp;&nbsp; net_fnc <span style="font-weight: bold;">opcd</span>
evaluate( <span style="font-weight: bold;">net_out double &amp;
result, </span>const char * what ) {result = 0.0; return 0;}<br>




<br>




&nbsp;&nbsp;&nbsp; // you are responsible for deleting the output
string
(as you were in the example above)<br>




&nbsp;&nbsp;&nbsp; net_fnc <span style="font-weight: bold;">opcd</span>
get_error( <span style="font-weight: bold;">net_out char *&amp;
err</span>
) { err = (char *) global_err_strings[_last_error]; return 0; }<br>




&nbsp;&nbsp;&nbsp; <br>




&nbsp;&nbsp;&nbsp;&nbsp; /*<br>




&nbsp; &nbsp; &nbsp;&nbsp; In the function above, the allocation method
for
the string (on client side in this case)<br>




&nbsp; &nbsp; &nbsp;&nbsp; is new, so you delete it with
"delete [] err;"<br>




&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; To change it to malloc/free, use
"net_malloc" keyword:<br>




&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; net_fnc opcd get_error(
net_out net_malloc char *&amp; err ) ...<br>




&nbsp;&nbsp;&nbsp; */<br>




};<br>




</div>




<br>




Most people will face another ugly fact - custom data types. Let's
modify our class to use a custom struct as an error type:<br>




clc.h:<br>




<div style="margin-left: 40px;"><span style="font-family: monospace;">struct
ERR {</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; int e;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; const char *
explain;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ERR() : e(0),
explain(NULL) {}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">};</span><br style="font-family: monospace;">




<br style="font-family: monospace;">




<span style="font-family: monospace;">class Calculator</span><br style="font-family: monospace;">




<span style="font-family: monospace;">{</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; <span style="font-weight: bold;">ERR
_last_error;</span></span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ...</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; net_fnc opcd
get_error( </span><span style="font-weight: bold; font-family: monospace;">net_out ERR * err</span><span style="font-family: monospace;"> ) { if( err ) *err
= _last_error; return 0; }</span><br style="font-family: monospace;">




<span style="font-family: monospace;">};</span><br>




</div>




<br>




Coidgen will generate files as if nothing happened (it will detect
method change, so the major number will be changed), but you won't be
able to compile it.<br>




First, your client header knows nothing
about ERR struct, so add line "//{client" in front of the struct
and line "//}client" below it to include text between them to
client header.<br>




The second reason is that you don't have streaming
operators for the struct. Code generated by coidgen tries to stream
err argument using them, but compiler screams there. To
shut it up, we create them as follows:<br>




<div style="margin-left: 40px;"><span style="font-family: monospace;">//{client</span><br style="font-family: monospace;">




<span style="font-family: monospace;">struct ERR {</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; int e;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; const char *
explain;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ERR() : e(0),
explain(NULL) {}</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; ~ERR() {</span><br style="font-family: monospace;">




<span style="font-family: monospace;">#ifdef CLIENT__clc_h&nbsp;&nbsp;
&nbsp;&nbsp; // delete the string only
on client side (see below)</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp; delete [] (char *) explain;</span><br style="font-family: monospace;">




<span style="font-family: monospace;">#endif</span><br style="font-family: monospace;">




<span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; }</span><br style="font-family: monospace;">




<br style="font-family: monospace;">




<span style="font-weight: bold; font-family: monospace;">&nbsp;&nbsp;&nbsp;
friend binstream
&amp; operator &lt;&lt; ( binstream &amp; out, const ERR &amp; x ) {
return out &lt;&lt; x.e &lt;&lt; x.explain; }</span><br style="font-weight: bold; font-family: monospace;">




<span style="font-weight: bold; font-family: monospace;">&nbsp;&nbsp;&nbsp;
friend binstream
&amp; operator &gt;&gt; ( binstream &amp; in, ERR &amp; x ) {</span><br style="font-weight: bold; font-family: monospace;">




<span style="font-weight: bold; font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
if( x.explain ) {delete [] <span style="font-weight: bold;"></span>(char
*) x.explain; x.explain = NULL;}</span><br style="font-weight: bold; font-family: monospace;">




<span style="font-weight: bold; font-family: monospace;">&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;
return in &gt;&gt; x.e &gt;&gt; x.explain;</span><span style="font-family: monospace;">&nbsp;&nbsp; &nbsp;&nbsp; /// notice
the FIFO order (first in, first out)</span><br style="font-weight: bold; font-family: monospace;">




<span style="font-weight: bold; font-family: monospace;">&nbsp;&nbsp;&nbsp;
}</span><br style="font-weight: bold; font-family: monospace;">




<span style="font-family: monospace;">};</span><br style="font-family: monospace;">




<span style="font-family: monospace;">//}client</span><br>




</div>




<br>




Streaming operators for common types has already been written, so
implementation is simple. Remember to write exactly the same number of
bytes to stream as you read from it. And remember that stream does not
react as a stack, it's a FIFO (First In First Out).<br>




Notice the hack in destructor above that makes it react different on
client and service
(server) side. Strings on the server are constant (==&gt; we do not
delete them), but when they are transfered to client, they need some
memory to be allocated ==&gt; client
allocates it during method call and then it must be freed in destructor.<br>




<br>




<br>




<br>




<br>




<br>




<big><big><span style="font-weight: bold;"><a name="Keywords"></a>Keywords<br>




<br>




</span></big></big>
<table style="text-align: left; width: 100%;" border="1" cellpadding="2" cellspacing="2">




  <tbody>




    <tr>




      <td colspan="1" rowspan="3" style="vertical-align: top; text-align: center; font-style: italic; text-decoration: underline;">global<br>




      </td>




      <td style="vertical-align: top; font-family: monospace;">/*{client_only<br>




}client_only*/<br>




      </td>




      <td style="vertical-align: top;">these keywords mark start and
end of text that
will be copied into client header, e.g.:<br>




      <span style="font-family: monospace;">/*{client_only</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">#define
INT_CLIENT_PTR&nbsp; void *</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">}client_only*/</span><br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">//{client<br>




//}client</td>




      <td style="vertical-align: top;">mark start and end of text that
will be copied into client header<br>




(this one is "active" in the service header, too)<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">"NET_RELEASE:"</td>




      <td style="vertical-align: top;">sets device release version,
can be placed anywhere in any comment at global scope (max. 8
characters)<br>




e.g. <span style="font-family: monospace;">// NET_RELEASE: 1.3.3</span><br>




or <span style="font-family: monospace;">/* current release is
NET_RELEASE: "
2 beta " */</span> </td>




    </tr>




    <tr>




      <td colspan="1" rowspan="2" style="vertical-align: top; text-align: center; font-style: italic; text-decoration: underline;">class<br>




      </td>




      <td style="vertical-align: top; font-family: monospace;">"NET_OPTIONS:"<br>




      </td>




      <td style="vertical-align: top;">sets options for the class (must
be placed inside a line comment). Available options are: not_autonomous
(default), bindable,&nbsp;acceptor_port, acceptor_bound_session,
direct, interprocess, remote, nolog_system_calls, nolog (see<span style="color: rgb(204, 0, 0);"> <a href="coid.html#options">special
coid options</a></span>). Example:<br>




      <span style="font-family: monospace;">class my_class {</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; //
NET_OPTIONS:&nbsp;</span><span style="font-family: monospace;">nolog_system_calls
      </span><span style="font-family: monospace;">acceptor_port 80 </span><span style="font-family: monospace;">direct</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">};</span><br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">"NET_DEPENDENCIES:"</td>




      <td style="vertical-align: top;">append list of service names
this
service depends on (requirements are the same as for <span style="font-family: monospace;">NET_OPTIONS</span>). For example:<br>




      <span style="font-family: monospace;">class my_class {</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">&nbsp;&nbsp;&nbsp; //
NET_DEPENDENCIES: abc, bcd cde; foo</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">};<br>




      </span>see <a href="coid.html#depend">coid dependencies</a><span style="font-family: monospace;"><br>




      </span> </td>




    </tr>




    <tr>




      <td colspan="1" rowspan="8" style="vertical-align: top; text-decoration: underline; font-style: italic; text-align: center;">method
      </td>




      <td style="vertical-align: top; font-family: monospace;">net_fnc<br>




      </td>




      <td style="vertical-align: top;">generate communication code for
this method<br>




(all keywords comes before method declaration)<br>




e.g. <span style="font-family: monospace;">net_fnc opcd
say_hello_world( const char * s );</span><br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_fnc_d</td>




      <td style="vertical-align: top;">flag for "net_fnc", method can
by used only by direct calls (default on)<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_fnc_i</td>




      <td style="vertical-align: top;">flag for "net_fnc", method can
by used only by interprocess calls (default on)</td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_fnc_r</td>




      <td style="vertical-align: top;">flag for "net_fnc", method can
by used only by network (remote) calls (default on)</td>




    </tr>




    <tr>




      <td style="vertical-align: top;"><span style="font-family: monospace;">net_fnc_di</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">net_fnc_id</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">net_fnc_dr</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">net_fnc_rd</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">net_fnc_ri</span><br style="font-family: monospace;">




      <span style="font-family: monospace;">net_fnc_ir</span><br>




      </td>




      <td style="vertical-align: top;">and all combinations of the flags
above<br>




      </td>




    </tr>




    <tr>




      <td colspan="1" rowspan="1" style="vertical-align: top; font-family: monospace;">net_fnc_s</td>




      <td style="vertical-align: top;">flag for "net_fnc", special
function will follow. Special functions create an optional interface
for common events, see <a href="coid.html#methods">special coid methods</a><br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_nolog</td>




      <td style="vertical-align: top;">do not log method calls<br>




      </td>




    </tr>




    <tr>

      <td><code>net_meta</code></td>

      <td>this method can be called through one of the <a href="formatting_stream.html">formatting binstreams</a>, that use the <a href="metastream.html">metastream</a> class to read and write&nbsp;data formatted in XML or various other structured formats.<br>

The&nbsp;types used in arguments of thusly marked methods must have a metastream &lt;&lt; operator defined. </td>

    </tr>

    <tr>




      <td colspan="1" rowspan="12" style="vertical-align: top; text-decoration: underline; font-style: italic; text-align: center;">argument<br>




      <br>




      <br>




      </td>




      <td style="vertical-align: top; font-family: monospace;">net_malloc</td>




      <td style="vertical-align: top;">argument will be allocated using
      <span style="font-family: monospace;">malloc</span> allocator
(default is '<span style="font-family: monospace;">new</span>') (only
out/inout arguments)</td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_count()<br>




      </td>




      <td style="vertical-align: top;">enter number of elements this
argument points to, e.g.:<br>




      <span style="font-family: monospace;">net_fnc opcd draw_point_3d(
net_in net_count(3) const float * pt );</span><br>




or<br>




      <span style="font-family: monospace;">net_fnc opcd draw_lines_3d(
net_in net_count(3*nlines) const float *
pts, int nlines );</span><br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_in</td>




      <td style="vertical-align: top;">specifies an input argument
(default)<br>




e.g. <span style="font-family: monospace;">net_fnc opcd
say_hello_world( net_in const char * s );</span><br>




it's equal to <span style="font-family: monospace;">net_fnc opcd
say_hello_world( const char * s );</span></td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_out</td>




      <td style="vertical-align: top;">specifies an output argument<br>




for pointers, client is responsible to free/delete them<br>




implementation sets the passed-in object<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_inout<br>




      </td>




      <td style="vertical-align: top;">specifies an input-output
argument<br>




for pointers, client is responsible to free/delete them<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_fetch</td>




      <td style="vertical-align: top;">specifies fetch argument - an
output argument, that's transfered from server to dispatch method as a
pointer/reference and streamed there without copying (implementation
returns pointer or reference to existing object).<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top;"><code>net_log</code></td>




      <td style="vertical-align: top;">log this argument to console.
Arrays (arguments with <span style="font-family: monospace;">net_count</span>
keyword) are not logged by default, you can enable them with this
keyword.<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">net_nolog</td>




      <td style="vertical-align: top;">do not log this argument (almost
all
arguments are written to console output, so prevent huge data from
flooding it). </td>




    </tr>




    <tr>




      <td style="vertical-align: top;"><span style="font-family: monospace;">net_ptr</span><br>




      </td>




      <td style="vertical-align: top;">"hides" an asterix (*), so you
can transfer pointers this way. <br>



Usually used together with net_fnc_d export keyword before the method, as the physical memory address is process-specific.<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top;"><span style="font-family: monospace;">net_account</span><br>




      </td>




      <td style="vertical-align: top;">use it as an argument keyword in
      <span style="font-family: monospace;">accept_connect()</span> or <span style="font-family: monospace;">accept_connect_shared()</span> to
indicate argument "<span style="font-family: monospace;">account_id
&amp; acc"</span> that will be checked in internal coid authorization
database (<span style="font-family: monospace;">cmd_interface::set_identity()</span>)
      <span style="font-weight: bold;">after</span> successful call<span style="font-weight: bold;">.</span> <span style="font-family: monospace;">accept_connect</span> method is
expected to return valid values in the <span style="font-family: monospace;">account_id </span>structure and must
return 0. Authentification will be considered successful if both <span style="font-family: monospace;">accept_connect()</span> method and <span style="font-family: monospace;">set_identity()</span> (called in
dispatch right after <span style="font-family: monospace;">accept_connect</span>)
are successful.<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top;"><span style="font-family: monospace;">net_map</span><br>




      </td>




      <td style="vertical-align: top;">change argument type on client
side, e.g.:<br>




      <span style="font-family: monospace;">net_map(int) unsigned
int&nbsp; arg</span><br>




will make coidgen use <span style="font-family: monospace;">int</span>
on client side instead of&nbsp; <span style="font-family: monospace;">unsigned
int</span>.<br>




      <span style="font-weight: bold;">Note:</span> Both types must be
binary compatible, i.e. produce the same binary data when streamed to a
stream, and due to direct calls (within the same process), your method
may receive both types of argument, so think twice before you use it.<br>




If you want to use different types that stream the same way but direct
calls would crash, use <span style="font-family: monospace;">net_remap</span>
(see below).<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top;"><span style="font-family: monospace;">net_remap</span><br>




      </td>




      <td style="vertical-align: top;">the same as <span style="font-family: monospace;">net_map</span> except coidgen
generates a workaround for direct calls to make it safe to call this
method directly from client (with changed argument type).<br>




For example:<br>




      <span style="font-family: monospace;">net_remap(client_side_struct
&amp;) server_side_struct &amp;&nbsp; arg<br>




      </span>You don't have to include server-side includes, just
define similar struct which streams <span style="font-weight: bold;">exactly</span>
the same way.<span style="font-family: monospace;"><br>




      </span></td>




    </tr>




    <tr>




      <td colspan="1" rowspan="3" style="vertical-align: top; text-decoration: underline; font-style: italic; text-align: center;">common<br>




types<br>




      </td>




      <td style="vertical-align: top; font-family: monospace;">cmd_interface</td>




      <td style="vertical-align: top;">a common command interface you
can use to communicate with the framework to obtain various data, see
coid/coidsvc/cmdin.h</td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;"><a href="opcd_type.html">opcd</a></td>




      <td style="vertical-align: top;">return type, see
coid/comm/retcodes.h</td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">command_tokens</td>




      <td style="vertical-align: top;">used in <span style="font-family: monospace;">accept_command()</span> method, see
coid/comm/str.h</td>




    </tr>




    <tr>




      <td colspan="1" rowspan="4" style="vertical-align: top; text-align: center; font-style: italic; text-decoration: underline;">common<br>




headers<br>




      </td>




      <td style="vertical-align: top; font-family: monospace;">coid/coidsvc/coidsvc.h</td>




      <td style="vertical-align: top;">basic service header #include,
you have to include it to service header to compile it without errors</td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">coid/coidsvc/coid.h</td>




      <td style="vertical-align: top;">basic keywords<br>




      </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">coid/coidsvc/cmdin.h<br>




      </td>




      <td style="vertical-align: top;">command interface, use its
methods
to write to console, obtain service names, set/get their
options, .... </td>




    </tr>




    <tr>




      <td style="vertical-align: top; font-family: monospace;">coid/coidclient/coidclient.h</td>




      <td style="vertical-align: top;">client base class and
implementation<br>




      </td>




    </tr>




  
  
  
  
  </tbody>
</table>




<big><big><span style="font-weight: bold;"><br>




</span></big></big><br>




<br>




<br>




<br>




<br>




<big style="font-weight: bold;"><big><a name="Command_line_arguments"></a>Command
line arguments</big></big><br>




<br>




Only <span style="font-weight: bold;">-f</span> command line argument
is supported now (coidgen version 0.4.4). It forces re-generation of
client and dispatch files (by default this is skipped if no changes
were detected in the service header file).<br>




<br>




<br>




<br>




<br>




<br>




<br>




<span style="font-weight: bold;"><a name="See_also"></a>See also:<br>




</span>
<div style="margin-left: 40px;"><a href="function_argument_format.html">Function
argument format</a> - table containing supported formats of arguments
and their declarations in dispatch.cpp and client.cpp<br>




<a href="coid.html">Coid special options and methods</a><br>




</div>




<br>




<br>




<br>




<big><big><span style="font-weight: bold;"></span></big></big><br>




<br>




<a href="#Contents">back to top</a><br>




<br>




</body>
</html>
